# 2023 年用来中业统计 git 提交记录的
#
# coding = utf-8
# coding = utf-8
# !/usr/bin/python3
# coding=utf8
import itertools
import math
import threading
import time
import gitlab
import datetime
from tabulate import tabulate
from concurrent.futures import ThreadPoolExecutor

url = 'http://172.16.1.35/'  # gitlab安装地址
private_token = '3BR39ojVPcf84Zn7yT6W'  # 王志华的
# private_token = 'Jepk7GfqhD72UHh3VgL-'  # gitlab 就是上面我自己的
currentName = "wangzhihua"  # 统计某个用户的，写名字即可
flag = False  # 是否是统计某个用户标志，设置为false为统计所有用户
# 这传的是UTC时间
start_time = '2023-10-15T16:00:00Z'
end_time = '2023-10-18T03:00:00Z'
info = []

# 登录 获取gitlab操作对象gl
gl = gitlab.Gitlab(url, private_token)

# 创建线程池，最多维护10个线程
threadpool = ThreadPoolExecutor(100)

pageSize = 2

# 实例化队列对象
# q = queue.Queue(100000)

A_lock = threading.Lock()


def detail(projects1):
    global info
    for project in projects1:  # 遍历每一个项目
        # print("1")
        p1 = [project]
        for p, b in itertools.product(p1, project.branches.list(get_all=True)):
            commits = p.commits.list(get_all=True, query_parameters={'since': start_time, 'until': end_time,
                                                                     'ref_name': b.name})  # 根据时间、分支名遍历该分支下面所有的提交记录
            ids = []
            for c in commits:
                ids.append(c.id)
            for p2, di in itertools.product(p1, ids):
                com = p2.commits.get(di)
                if hasattr(com, "author_name") and hasattr(com, "stats"):
                    author_name = com.author_name
                    print("authorName:", author_name)
                    # global info
                    # print(com)
                    if "Merge" in com.title or "Merge" in com.message:  # 不统计合并操作
                        continue
                    if author_name == currentName and flag:
                        additions1 = com.stats['additions']
                        deletions1 = com.stats['deletions']
                        total1 = com.stats['total']
                        temp1 = {"name": author_name, "additions": additions1,
                                 "deletions": deletions1,
                                 "total": total1}  # Git工具用户名,新增代码数,删除代码数,总计代码数
                        # print(temp1)
                        A_lock.acquire()
                        info.append(temp1)
                        A_lock.release()
                        # print("current人执行中")
                    elif not flag:
                        additions2 = com.stats['additions']
                        deletions2 = com.stats['deletions']
                        total2 = com.stats['total']
                        temp2 = {"name": author_name, "additions": additions2,
                                 "deletions": deletions2,
                                 "total": total2}  # Git工具用户名,新增代码数,删除代码数,总计代码数
                        # print(temp2)
                        A_lock.acquire()
                        info.append(temp2)
                        A_lock.release()
                        # print("other人执行中")
            ids.clear()
            # print("2")
        p1.clear()
    # print("3")
    """for project in projects:  # 遍历每一个项目
        branches = project.branches.list(get_all=True)  # 把每个项目下面的所有分支查出来
        for branch in branches:  # 然后再遍历每一个分支
            commits = project.commits.list(get_all=True, query_parameters={'since': start_time, 'until': end_time,
                                                                           'ref_name': branch.name})  # 根据时间、分支名遍历该分支下面所有的提交记录
            for commit in commits:  # 然后再遍历每个提交记录，查询每个提交记录的人和量
                com = project.commits.get(commit.id)
                if hasattr(com, "author_name") and hasattr(com, "stats"):
                    name = com.author_name
                    if name == currentName and flag:
                        name = com.author_name
                        additions = com.stats['additions']
                        deletions = com.stats['deletions']
                        total = com.stats['total']
                        temp = {"name": name, "additions": additions,
                                "deletions": deletions,
                                "total": total}  # Git工具用户名,新增代码数,删除代码数,总计代码数
                        p.put(temp)
                        print("current人执行中")
                    elif not flag:
                        name = com.author_name
                        additions = com.stats['additions']
                        deletions = com.stats['deletions']
                        total = com.stats['total']
                        temp = {"name": name, "additions": additions,
                                "deletions": deletions,
                                "total": total}  # Git工具用户名,新增代码数,删除代码数,总计代码数
                        p.put(temp)
                        print("other人执行中")"""


# 生产者
def producer(projects2):
    detail(projects2)
    # print("生产者生产完毕")


# 消费者
def consumer(q3=None):
    global info
    A_lock.acquire()
    info.append(q3.get())
    A_lock.release()
    # print("消费者消费完毕", q3.get())


# def task(video_url):
#    print("开始执行任务", video_url)
#    time.sleep(1)
#    return 1


def done(response):  # response就是futuer对象，也就是task的返回值分装的一个Futuer对象
    print("任务执行完后，回调的函数", response.result())  # 即Futuer.result()：取出task的返回值


# futuer = threadpool.submit(task, url)  # futuer是由task返回的一个Future对象，里面有记录task的返回值
# futuer.add_done_callback(done)  # 回调done函数，执行者依然是子线程

# pages = (total + pageSize - 1) / pageSize;

# start = (page - 1) * per_page_num
# end = page * per_page_num
# page_data_list = data_list[start:end]

def producerData(pages2):
    for page1 in range(pages2):
        start = (page1 - 1) * pageSize
        end = page1 * pageSize
        pg = projects[start:end]
        # detail(projects, p)
        t = threading.Thread(target=producer(pg))
        t.start()
        # threadpool.submit(producer, pg)
    # print("生产完毕······")


def consumerData(pages3):
    for page in range(pages3):
        threadpool.submit(consumer)
    # print("消费完毕······")


if __name__ == "__main__":
    try:
        print("正在统计数据，请耐心等待，这将花费不少时间~")
        startTime = time.time()
        projects = gl.projects.list(get_all=True)  # 先把所有项目查出来
        total = len(projects)
        pages = (total + pageSize - 1) / pageSize
        pages = math.floor(pages)
        producerData(pages)
        # consumerData(pages)
        names = []  # Git工具用户名
        additions = []  # 新增代码数
        deletions = []  # 删除代码数
        totals = []  # 总计代码数
        res = {}
        # print("等待线程池中的任务执行完毕中······")
        # threadpool.shutdown(True)  # 等待线程池中的任务执行完毕后，在继续执行
        # print("等待线程池中的任务执行完毕······")
        # while len(info) == 0:
        #    time.sleep(1)
        # 生成元组
        print("infor.size:", len(info))
        for i in info:
            for key, value in i.items():
                if key == "name":
                    names.append(value)
                if key == "additions":
                    additions.append(value)
                if key == "deletions":
                    deletions.append(value)
                if key == "total":
                    totals.append(value)
        data = list(zip(names, additions, deletions, totals))
        # 去重累加
        for j in data:
            name = j[0]
            additions = j[1]
            deletions = j[2]
            total = j[3]
            if name in res.keys():
                res[name][0] += additions
                res[name][1] += deletions
                res[name][2] += total
            else:
                res.update({name: [additions, deletions, total]})

        # 打印结果
        # print("Git用户名 | 新增代码数 | 删除代码数 | 总计代码数")
        headers = ["用户名", "新增代码数", "删除代码数", "总计代码数"]
        # print(res)
        data = [[key] + value for key, value in res.items()]
        # print(result_list)
        # for k in res.keys():
        #     print(str(k) + '    |    ' + (str(res[k][0])) + '    |    ' +
        #           str(res[k][1]) + '    |    ' + str(res[k][2]) + "\n")
        table = tabulate(data, headers, stralign='left',
                         tablefmt="grid", showindex=True)
        print(table)
        endTime = time.time()
        currentTime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        print("统计时间段UTC: ", start_time + " -- " + end_time,
              "当前时间：", currentTime, "运行时间为：", endTime - startTime)
    except Exception as e:
        print("发生了异常", e)
